#include <gtest/gtest.h>
#include <mockcpp/mockcpp.hpp>
#include <string>
#include <iostream>

#define MOCKER_CPP(api, TT) MOCKCPP_NS::mockAPI(#api, reinterpret_cast<TT>(api))
#define private public
#define protected public

using std::string;
using std::cout;
using std::endl;

class STAT
{
public:
    static int get() 
    {
        return 0;
    }

    int pub_func()
    {
        // GlobalMockObject::reset();
        MOCKER_CPP(&STAT::pro_func, int(*)())
            .stubs()
            .will(returnValue(66));
        cout << "pro_func return : " << pro_func() << endl;
        // GlobalMockObject::verify();

        // GlobalMockObject::reset();
        MOCKER_CPP(&STAT::pri_func, int(*)())
            .stubs()
            .will(returnValue(666));
        cout << "pri_func return : " << pro_func() << endl;
    // GlobalMockObject::verify();
        return 0;
    }

protected:
    int pro_func()
    {
        return 0;
    }

private:
    int pri_func() 
    {
        return 0;
    }
};

TEST(sample, cpp_class_static_func)
{
    GlobalMockObject::reset();
    MOCKER_CPP(STAT::get, int(*)()) // 不用取地址
        .stubs()
        .will(returnValue(666));

    EXPECT_EQ(666, STAT::get());
    GlobalMockObject::verify();
}

TEST(sample, cpp_class_public_func)
{
    GlobalMockObject::reset();
    MOCKER_CPP(&STAT::pub_func, int(*)())
        .stubs()
        .will(returnValue(666));
    STAT stat;
    EXPECT_EQ(666, stat.pub_func());
    GlobalMockObject::verify();
}

TEST(sample, cpp_class_protected_func)
{
    GlobalMockObject::reset();
    MOCKER_CPP(&STAT::pro_func, int(*)())
        .stubs()
        .will(returnValue(666));
    STAT stat;
    EXPECT_EQ(666, stat.pro_func());
    GlobalMockObject::verify();
}

TEST(sample, cpp_class_private_func)
{
    GlobalMockObject::reset();
    MOCKER_CPP(&STAT::pri_func, int(*)())
        .stubs()
        .will(returnValue(666));
    STAT stat;
    EXPECT_EQ(666, stat.pri_func());
    GlobalMockObject::verify();
}

int main(int argc, char *argv[])
{
    STAT stat;
    stat.pub_func();

    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
